using System;

namespace SmartBoard.Core.Command
{
    public abstract class CommandBase:ICommand
    {
        #region Private Fields
        private bool _canExecute = true;
        #endregion

        #region ICommand Implementation

        public void Execute(object parameter)
        {
            object outputData;
            if (_canExecute && PrepareData(parameter, out outputData))
            {
                DoExecution(outputData);
                OnExecutionDone(outputData);
            }
        }

        public bool RaiseCanExecute(object parameter)
        {
            return CanExecute = GetCanExecute(parameter);
        }

        public bool CanExecute
        {
            get
            {
                return _canExecute;
            }
            set
            {
                if (_canExecute == value)
                    return;
                _canExecute = value;
                OnCanExecuteChanged();
            }
        }

        public int CommandId
        {
            get { return GetCommandId(); }
        }

        #endregion

        #region Protected Virtuals
        protected virtual bool PrepareData(object inputData, out object outputData)
        {
            outputData = inputData;
            return true;
        }

        protected virtual void DoExecution(object outputData)
        { }

        protected virtual bool GetCanExecute(object parameter)
        {
            return true;
        }

        protected virtual void OnExecutionDone(object parameter)
        { }

        protected virtual void OnCanExecuteChanged()
        { }

        protected abstract int GetCommandId();
        #endregion
    }
}